home *** CD-ROM | disk | FTP | other *** search
- ;---------------------------------------------------------------
- ; INSERT.ASM
- ;
- ; IN MICROSOFT MACRO ASSEMBLER SOURCE CODE
- ;
- ; PURPOSE:
- ; Insert data or blank columns into a text file. Not only
- ; string data, but the carriage return [CR], line feed [LF],
- ; and/or form feed [FF] characters can be inserted. Can be
- ; used with the pipe or redirection function.
- ;
- ; SYNTAX: INSERT /n/ [<"data string">] [CR] [FF] [LF] /
- ; Where n = column or character position to start the
- ; insert (255 max). CR = carriage return, LF = line feed,
- ; and FF = form feed.
- ;
- ; EXAMPLE: INSERT /1/"NEW DATA"CRLF/
- ; Would insert the words NEW DATA and then a carriage return
- ; and line feed at the beginning of each line of the input
- ; file. The result would be that NEW DATA would be
- ; inserted between each line of the input file.
- ;
- ; EXAMPLE: INSERT /9/CRLF/ < OLDDATA.TXT > NEWDATA.TXT
- ; Would insert CR and LF at position 9 on each line of the
- ; file OLDDATA.TXT and store it in a file named NEWDATA.TXT.
- ;
- ; <C> DEC. 1986 PAUL BAKER CLEVELAND TN
- ;---------------------------------------------------------------
- PAGE ,132
- dosint MACRO function ; call the DOS interrupt
- MOV AH,function ; put function number in AH
- INT 21h
- ENDM
-
-
- code SEGMENT byte public 'code'
- ASSUME CS:CODE,DS:DATA,SS:STACK
- ORG 0100H
- STRT:
- PUSH DS ; DO HOUSEKEEPING TO
- SUB AX,AX ;ALLOW RETURN TO DOS
- PUSH AX
- MOV AX,DATA
- MOV ES,AX ; set ES to top of data seg.
- CLD
- XOR CX,CX ; clear CX
- MOV BX,CX ; clear BX
- MOV SI,0080h ; point to PSP
- LODSB ; find how many params
- MOV CL,AL ; CL has count of params
- CMP CL,00h ; if no params then show
- JNZ not_zero ; use instructions.
- MOV DX,OFFSET use_msg
- PUSH ES
- POP DS ; get local data segment.
- dosint 09h ; display help screen.
- IRET ; return to DOS.
- not_zero: CMP CL,07h ; 7 is min. # of params.
- JB bad_param ; if < 7 then error.
- INC SI ; skip first space
- LODSB ; see if / is present
- CMP AL,2Fh
- JNE bad_param ; if no / then error.
- SUB CX,0002h ; adjust param count.
- MOV DI,OFFSET strt_data ; set to top of buffer.
- get_strt: LODSB ; load next param.
- DEC CX
- CMP AL,2Fh ; if / then must be end
- JZ get_insert ; of first parameter
- CMP CX,0000h ;
- JBE bad_param ; if last param then leave.
- CMP AL,30h ; if not a number between
- JB bad_param ; 0 & 9 then exit
- CMP AL,39h ; and give error
- JG bad_param ; message.
- INC BL ; bump digit count.
- CMP BL,03h ; three digits max.
- JG bad_param ; if more than 3 then error.
- SUB AL,30h ; convert to binary.
- CALL store_byte ; store each digit.
- JMP get_strt ; get next param
- get_insert: MOV DI,OFFSET insert_data ; load top of buffer
- CMP BL,00h ; if no first param then
- JLE bad_param ; send error message.
- MOV BH,00h ; BH will count insert bytes.
- LODSB ; get next param.
- DEC CX ; reduce param count.
- CMP AL,22h ; in quotes ?
- JZ in_quotes ; if so then go process.
- CMP AL,2Fh ; if another / then
- JZ bad_param ; invalid parameter.
- no_quotes: MOV AH,AL ; move low byte to high byte
- LODSB ; load next byte.
- DEC CX ; reduce param count.
- CALL caps ; force upper case.
- CMP AX,4352h ; if CR.
- JZ cr
- CMP AX,4C46h ; if LF.
- JZ lf
- CMP AX,4646h ; if FF.
- JZ ff
- JMP bad_param ; else must be error.
- bad_param: MOV DX,OFFSET err1 ; point to error message
- MOV CX,2Fh ; send 47 bytes.
- MOV BX,0002h ; send to error output.
- PUSH ES
- POP DS ; get new data segment
- dosint 40h ; display it
- leave: IRET ; RETURN TO DOS
- cr: MOV AL,0Dh ; load CR byte.
- JMP put_insert
- lf: MOV AL,0Ah ; load LF byte.
- JMP put_insert
- ff: MOV AL,0Ch ; load FF byte.
- put_insert: CALL store_byte ; store insert info.
- INC BH ; bump insert byte count.
- LODSB ; get next param.
- CMP AL,2Fh ; if / then must be end
- JZ process ; of parameters.
- CMP AL,22h ; if quotes then
- JZ in_quotes ; is in quotes again.
- JMP no_quotes ; else loop back.
- in_quotes: LODSB
- CMP AL,22h ; if " then out of quotes.
- JNE in_quotes1 ; if not " then go on.
- LODSB ; else get next after ".
- CMP AL,2Fh ; if / then must be end
- JZ process
- JMP no_quotes
- in_quotes1: CMP AL,2Fh ; if / then must be error
- JZ bad_param ; since no closing ".
- CALL store_byte ; store current byte.
- INC BH ; bump insert byte count.
- JMP in_quotes ; loop back.
- ;
- ; ----------- PROCESS INCOMING DATA -------------------
- ;
- process:
- PUSH ES ; load local data pointer.
- POP DS
- MOV insert_len,BH ; store insert length.
- MOV digit_cnt,BL ; store digit count.
- MOV AX,01h ; start AX @ 1
- XOR CX,CX ; clear CX register.
- MOV CL,digit_cnt ; load loop count.
- loop1: MUL mult10 ; multiply by 10
- LOOP loop1 ; create multiplier
- MOV BX,AX ; save multiplier.
- MOV CL,digit_cnt ; load loop count.
- MOV SI,OFFSET strt_data ; point to 1'st digit
- loop2: MOV AX,BX ; get multiplier.
- DIV mult10 ;
- MOV AH,00h ; clear remainder.
- MOV BX,AX ; update multiplier.
- MUL BYTE PTR [SI] ; multiply current digit.
- ADD strt_col,AL ; update start col #.
- INC SI ; bump pointer.
- LOOP loop2
- get_ready: XOR BX,BX ; load handle 00
- dosint 45h ; get file duplicate.
- MOV BP,AX ; set base pointer to handle.
- dosint 3Eh ; close file.
- ; MOV BX,0002h ;
- ; dosint 45h ; file duplicate.
- read_data: CLD
- MOV DX,OFFSET data_buf ; store in data_buf
- MOV CX,800h ; set to read 800h bytes.
- MOV BX,BP ; set BX to file handle.
- dosint 3Fh ; read input data.
- OR AX,AX ; data read ?
- JNZ more_data
- no_data: IRET
- more_data: MOV CX,AX ; CX has count of bytes read.
- MOV SI,DX ; point to top of data.
- get_byte: MOV BL,strt_col ; see if this is
- CMP BL,col_cnt ; where the insert goes.
- JNZ no_hit ; if not, then no hit.
- CALL make_insert ; else make insert.
- no_hit: LODSB ; get first byte.
- CMP AL,1Ah ; if end of file, quit.
- JZ no_data
- CMP AL,0Dh ; cr ?
- JNZ no_cr ; if not, go on.
- MOV col_cnt,01h ; else reset column count.
- MOV DL,AL ; send the CR
- dosint 02h
- DEC CX ; reduce byte count.
- JMP no_hit ; get next byte.
- no_cr: CMP AL,09h ; check for tab.
- JNZ no_tab
- CALL tab ; if so, call tab routin.
- JMP get_byte ; loop back.
- no_tab: CMP AL,1Fh ; do not count anything
- JBE no_count ; else below 20h.
- send_byte: INC col_cnt ; bump column count.
- no_count: MOV DL,AL ; send byte to disply.
- dosint 02h
- DEC CX
- go_back: JCXZ read_data
- JMP get_byte
- IRET
- ;
- ; ---------- MAKE INSERT ROUTINE ------------------------
- ;
- make_insert: CMP insert_len,01h ; if nothing to insert
- JB exit_insert ; then leave.
- PUSH CX ; save CX and
- PUSH SI ; and SI info.
- MOV SI,OFFSET insert_data ; point to data.
- XOR CX,CX ; load CX with
- MOV CL,insert_len ; loop count.
- insert_loop: LODSB ; load next byte.
- MOV DL,AL
- dosint 02h ; send byte out.
- LOOP insert_loop
- POP SI ; restore SI and
- POP CX ; CX data.
- exit_insert: RET
- ;
- ;---------------- TAB ROUTINE ---------------------------
- ;
- tab: MOV CX,0008h ; expand tabs count.
- MOV DL,20h ; load space byte.
- tab_loop: CMP BL,col_cnt ; time to make insert ?
- JNZ not_yet ;
- CALL make_insert ; if so, then call insert.
- MOV DL,20h ; reload space byte.
- not_yet: dosint 02h ; send byte.
- INC col_cnt ; bump column count.
- LOOP tab_loop ; loop back.
- RET
- ;
- ; --------------- CAPS ROUTINE --------------------------
- ;
- caps: CMP AL,61h ; convert to
- JB exit_caps ; all caps.
- CMP AL,7Ah
- JG exit_caps
- AND AX,5F5Fh
- exit_caps: RET
- ;
- ; ---------- STORE BYTE ROUTINE -----------------------------
- ;
- store_byte: PUSH DS ; store current DS
- PUSH ES ; local data segment info.
- POP DS ; exchange them.
- STOSB ; store local data.
- PUSH DS
- POP ES ; restore original
- POP DS ; positions.
- RET
- CODE ENDS
-
- ;
- ; ------------ STACK SEGMENT -----------------------------
- ;
- stack SEGMENT STACK 'stack'
- DB 32 DUP(?)
- stack ENDS
-
- ;
- ; ------------- DATA SEGMENT --------------------------------
- ;
- data SEGMENT byte public 'DATA'
- err1 DB 'INSERT : error - missing or invalid paramaters $'
- strt_data DB 3h DUP (00h) ; start position as entered
- strt_col DB 00 ; column to start insert
- col_cnt DB 01h ; current column count.
- digit_cnt DB 00h ; # of digits in 1'st param
- insert_len DB 00h ; length of insert data string
- insert_data DB 80h DUP(?) ; buffer for insert data
- data_buf DB 800h DUP(?) ; buffer for input data.
- mult10 DB 0Ah ; times 10 multiplier.
- use_msg DB 13,10,'PURPOSE :',13,10,10
- DB ' Insert data or blank columns into a '
- DB 'text file. Not only string data, but',13,10
- DB ' the Carriage Return [CR], Line Feed [LF] and/or'
- DB ' Form Feed [FF] characters ',13,10
- DB ' can be inserted. Can be used with the pipe or '
- DB ' re-direction function.',13,10,10
- DB 'SYNTAX : INSERT /n/ [<"data string">] [CR] [FF] [LF] /',13,10
- DB 10,' Where n = column or character position'
- DB ' to start the insert. (255 max.)',13,10
- DB ' CR = Carriage Return, LF = Line Feed and FF = Form Feed'
- DB 13,10,10,'EXAMPLE : INSERT /1/"NEW DATA"CRLF/',13,10,10
- DB ' Would insert the words NEW DATA and then a carriage'
- DB ' return and line feed ',13,10
- DB ' at the begining of each line of the input file.'
- DB 'The result would be that',13,10
- DB ' NEW DATA would be inserted between each line'
- DB ' of the input file.',10,13,10
- DB 'EXAMPLE : INSERT /9/CRLF/ < OLDDATA.TXT > NEWDATA.TXT'
- DB 13,10,10,' Would insert CR and LF at position 9 on each'
- DB ' line of the file OLDDATA.TXT ',13,10
- DB ' and store it in a disk file'
- DB ' named NEWDATA.TXT.',13,10,10
- DB ' <C> DEC. 1986 PAUL BAKER $'
- data ENDS
- END STRT
- isk file'
- DB ' named NEWDATA.TXT.',13,10,10
- DB '